#include "config_helper.h"
#include "hbase.h"
#include "hlog.h"
#include "hloop.h"
#include "hplatform.h"
#include "hversion.h"
#include "version.h"
#include <stdio.h>

#define CUSTOM_LOG_FORMAT "[%y-%m-%dT%H:%M:%S.%z] [%l] %s"

conf_ctx_t g_conf_ctx;

void conf_ctx_init(conf_ctx_t* ctx) {
    ctx->parser       = new IniParser;
    ctx->loglevel     = LOG_LEVEL_DEBUG;
    ctx->service_port = 0;
    ctx->czgw_port    = 0;
}

void mylogger(int loglevel, const char* buf, int len) {
    if (loglevel >= LOG_LEVEL_INFO) {
        stdout_logger(loglevel, buf, len);
    }

    if (loglevel >= LOG_LEVEL_INFO) {
        file_logger(loglevel, buf, len);
    }
}

int parse_confile(const char* confile) {
    int ret = g_conf_ctx.parser->LoadFromFile(confile);
    if (ret != 0) {
        printf("Load confile [%s] failed: %d\n", confile, ret);
        exit(-40);
    }

    // basedir
    std::string str = g_conf_ctx.parser->GetValue("basedir");
    if (!str.empty()) {
        hv_mkdir(str.c_str());
        g_conf_ctx.basedir = str;
        // 指定pid文件名
        str = str + g_main_ctx.program_name + ".pid";
        memcpy(g_main_ctx.pidfile, str.c_str(), str.size());
    }

    // log_path
    str = g_conf_ctx.parser->GetValue("log_path");
    if (!str.empty()) {
        g_conf_ctx.log_path = g_conf_ctx.basedir + str;
        hv_mkdir(g_conf_ctx.log_path.c_str());
    }

    // logfile
    str = g_conf_ctx.parser->GetValue("logfile");
    if (!str.empty()) {
        str = g_conf_ctx.log_path + str;
        strncpy(g_main_ctx.logfile, str.c_str(), sizeof(g_main_ctx.logfile));
    }

    hlog_destory();
    hlog_set_file(g_main_ctx.logfile);

    // db_path
    str = g_conf_ctx.parser->GetValue("db_path");
    if (!str.empty()) {
        g_conf_ctx.db_path = g_conf_ctx.basedir + str;
        hv_mkdir(g_conf_ctx.db_path.c_str());
    }

    // dist_path
    str = g_conf_ctx.parser->GetValue("dist_path");
    if (!str.empty()) {
        g_conf_ctx.dist_path = g_conf_ctx.basedir + str;
        hv_mkdir(g_conf_ctx.dist_path.c_str());
    }

    // records_path
    str = g_conf_ctx.parser->GetValue("records_path");
    if (!str.empty()) {
        g_conf_ctx.records_path = g_conf_ctx.basedir + str;
        hv_mkdir(g_conf_ctx.records_path.c_str());
    }

    // snapshot_path
    str = g_conf_ctx.parser->GetValue("snapshot_path");
    if (!str.empty()) {
        g_conf_ctx.snapshot_path = g_conf_ctx.basedir + str;
        hv_mkdir(g_conf_ctx.snapshot_path.c_str());
    }

    // loglevel
    str = g_conf_ctx.parser->GetValue("loglevel");
    if (!str.empty()) {
        hlog_set_level_by_str(str.c_str());
    }
    // log_filesize
    str = g_conf_ctx.parser->GetValue("log_filesize");
    if (!str.empty()) {
        hlog_set_max_filesize_by_str(str.c_str());
    }
    // log_remain_days
    str = g_conf_ctx.parser->GetValue("log_remain_days");
    if (!str.empty()) {
        hlog_set_remain_days(atoi(str.c_str()));
    }
    // log_fsync
    str = g_conf_ctx.parser->GetValue("log_fsync");
    if (!str.empty()) {
        g_conf_ctx.log_fsync = hv_getboolean(str.c_str());
        logger_enable_fsync(hlog, g_conf_ctx.log_fsync);
    }

    hlog_set_handler(mylogger);
    hlog_set_format(CUSTOM_LOG_FORMAT);
    // logger_enable_color(hlog, 1);

    // first log here
    hlogi("%s version: %s", g_main_ctx.program_name, hv_compile_version());
    hlog_fsync();

    // service_port
    int service_port = 0;
    service_port     = g_conf_ctx.parser->Get<int>("service_port");
    if (service_port == 0) {
        printf("Please config service port!\n");
        exit(-10);
    }
    g_conf_ctx.service_port = service_port;

    // czgw_port
    int czgw_port = 0;
    czgw_port     = g_conf_ctx.parser->Get<int>("czgw_port");
    if (czgw_port == 0) {
        printf("Please config czgw port!\n");
        exit(-10);
    }
    g_conf_ctx.czgw_port = czgw_port;

    int records_size = 0;
    records_size     = g_conf_ctx.parser->Get<int>("records_size");
    if (records_size == 0) {
        printf("Please config czgw port!\n");
        exit(-10);
    }
    g_conf_ctx.records_size = records_size;

    int snapshot_size = 0;
    snapshot_size     = g_conf_ctx.parser->Get<int>("snapshot_size");
    if (snapshot_size == 0) {
        printf("Please config czgw port!\n");
        exit(-10);
    }
    g_conf_ctx.snapshot_size = snapshot_size;
    hlogi("parse_confile('%s') OK", confile);
    return 0;
}

void print_version() {
    // printf("%s version %s\n", g_main_ctx.program_name, hv_compile_version());
    printf("%s version %s\n", g_main_ctx.program_name, GITLAB_FETCH_ID);
}

void print_help(const option_t* long_options, int opt_size) {
    char detail_options[1024] = {0};
    dump_opt_long(long_options, ARRAY_SIZE(long_options), detail_options, sizeof(detail_options));
    printf("%s\n", detail_options);
}

void on_signal(hsignal_t* sig) {
    hloge("on_signal signo=%d", (int)hevent_id(sig));
    hloop_stop(hevent_loop(sig));
    hlog_fsync();
}
